import ndService from '@/api/NdService'
import cacheManage from '@/cache/CacheManage'
import layoutService from '@/api/LayoutService'
import nvService from '@/api/NvService'
import ConstDef from "@/js/ConstDef";

class NvsDataUtils {
  async getNdAndLayout(ndCode, layoutCode) {
    const commonInfo = cacheManage.getDefaultCommonInfo();
    const result = { success: true, nd: null, layout: null, message: null }
    const ndMsg = await ndService.getNd(commonInfo, ndCode);
    if (!ndMsg.success) {
      result.message = ndMsg.message;
      return result;
    } else { result.nd = ndMsg.value; }

    const layoutMsg = await layoutService.getLayout(commonInfo, layoutCode);

    if (!layoutMsg.success) {
      result.message = layoutMsg.message;
      return result;
    } else { result.layout = layoutMsg.value; }

    return result;
  }

  async getNvAndNdAndLayout(nvId, ndCode, layoutCode, getNvApiInfo) {
    const result = await this.getNdAndLayout(ndCode, layoutCode);
    if (!result.success) { return result; }
    const commonInfo = cacheManage.getDefaultCommonInfo();
    const nvMsg = await getNvApiInfo.func.call(getNvApiInfo.obj, commonInfo, ndCode, nvId);
    if (!nvMsg.success) {
      result.message = nvMsg.message;
      result.success = false;
      return result;
    }
    result.nv = nvMsg.value;
    return result;
  }

  async copyNvAndNdAndLayout(sourceNvId, ndCode, layoutCode) {
    const result = await this.getNdAndLayout(ndCode, layoutCode);
    if (!result.success) { return result; }
    const commonInfo = cacheManage.getDefaultCommonInfo();
    const nvMsg = await nvService.copyNv(commonInfo, ndCode, sourceNvId);
    if (!nvMsg.success) {
      result.message = nvMsg.message;
      result.success = false;
      return result;
    }
    result.nv = nvMsg.value;
    return result;
  }

  async getNvAndNdAndLayoutByCode(nvCode, codeFdName, ndCode, layoutCode, getNvByCodeApiInfo) {
    const result = await this.getNdAndLayout(ndCode, layoutCode);
    if (!result.success) { return result; }
    const commonInfo = cacheManage.getDefaultCommonInfo();
    const nvMsg = await getNvByCodeApiInfo.func.call(getNvByCodeApiInfo.obj, commonInfo, ndCode, nvCode, codeFdName);
    if (!nvMsg.success) {
      result.message = nvMsg.message;
      result.success = false;
      return result;
    }
    result.nv = nvMsg.value;
    return result;
  }

  async initNvAndNdAndLayout(ndCode, layoutCode) {
    const result = await this.getNdAndLayout(ndCode, layoutCode);
    if (!result.success) { return result; }
    const commonInfo = cacheManage.getDefaultCommonInfo();
    const nvMsg = await nvService.initNv(commonInfo, ndCode);
    if (!nvMsg.success) {
      result.message = nvMsg.message;
      result.success = false;
      return result;
    }
    result.nv = nvMsg.value;
    return result;
  }

  searchNvs(objectNv, currentNvs, currentNd) {
    for (const tempNv of currentNvs) {
      if (tempNv === objectNv) { return currentNvs; }
    }
    for (const tempNv of currentNvs) {
      for (const childNd of currentNd.children) {
        const result = this.searchNvs(objectNv, tempNv[childNd.ndName], childNd);
        if (result) { return result; }
      }
      if (currentNd.cursive) {
        const result = this.searchNvs(objectNv, tempNv[currentNd.ndName], currentNd);
        if (result) { return result; }
      }
    }
    return null;
  }

  searchNvsById(nvId, currentNvs, currentNd) {
    for (const tempNv of currentNvs) {
      if (tempNv.id === nvId) { return currentNvs; }
    }
    for (const tempNv of currentNvs) {
      for (const childNd of currentNd.children) {
        const result = this.searchNvsById(nvId, tempNv[childNd.ndName], childNd);
        if (result) { return result; }
      }
      if (currentNd.cursive) {
        const result = this.searchNvsById(nvId, tempNv[currentNd.ndName], currentNd);
        if (result) { return result; }
      }
    }
    return null;
  }

  searchAndDeleteNvById(nvId, currentNvs, currentNd) {
    for (let index = 0; index < currentNvs.length; index++) {
      const tempNv = currentNvs[index];
      if (tempNv.id === nvId) {
        currentNvs.splice(index, 1);
        return true;
      }
    }
    for (const tempNv of currentNvs) {
      for (const childNd of currentNd.children) {
        const result = this.searchAndDeleteNvById(nvId, tempNv[childNd.ndName], childNd);
        if (result) { return result; }
      }
      if (currentNd.cursive) {
        const result = this.searchAndDeleteNvById(nvId, tempNv[currentNd.ndName], currentNd);
        if (result) { return result; }
      }
    }
    return false;
  }

  searchNvById(id, currentNvs, currentNd) {
    for (const tempNv of currentNvs) {
      if (tempNv.id === id) { return tempNv; }
    }
    for (const tempNv of currentNvs) {
      for (const childNd of currentNd.children) {
        const result = this.searchNvById(id, tempNv[childNd.ndName], childNd);
        if (result) { return result; }
      }
      if (currentNd.cursive) {
        const result = this.searchNvById(id, tempNv[currentNd.ndName], currentNd);
        if (result) { return result; }
      }
    }
    return null;
  }

  getLayoutExtension(layout, extensionType) {
    return layout.layoutExtensions.filter((item) => { return item.type === extensionType })
  }

  getFdLayoutExtension(fdLayout, extensionType) {
    return fdLayout.fdLayoutExtensions.filter((item) => { return item.type === extensionType })
  }

  setNvChangeOperationFlag(currentNv, currentNd) {
    if (currentNv.operationFlag === ConstDef.OPERATION_FLAG_UNCHANGED) { currentNv.operationFlag = ConstDef.OPERATION_FLAG_UPDATE; }
    for (const childNd of currentNd.children) {
      if (currentNv[childNd.ndName] && currentNv[childNd.ndName].length > 0) {
        for (const childNv of currentNv[childNd.ndName]) {
          this.setNvChangeOperationFlag(childNv, childNd);
        }
      }
    }
    if (currentNd.cursive) {
      if (currentNv[currentNd.ndName] && currentNv[currentNd.ndName].length > 0) {
        for (const childNv of currentNv[currentNd.ndName]) {
          this.setNvChangeOperationFlag(childNv, currentNd);
        }
      }
    }
  }

  setNvsChangeOperationFlag(nvs, currentNd) {
    for (const nv of nvs) {
      this.setNvChangeOperationFlag(nv, currentNd);
    }
  }
}

const nvsDataUtils = new NvsDataUtils();
export default nvsDataUtils;
